---
description: Базовый компонент для создания интерактивных элементов, который автоматически адаптирует семантику и поведение под контекст.
---

<Overview group="utils">

# Tappable [tag:component]

Базовый компонент для создания интерактивных элементов, который автоматически адаптирует семантику и поведение под контекст.
Обрабатывает состояния наведения, нажатия и фокуса, обеспечивая:

- визуальную обратную связь через фоновые эффекты;
- ripple-эффект на Android;
- автоматическую установку `cursor: pointer`;
- основу для интерактивных компонентов вроде [`Button`](/components/button),
  [`Cell`](/components/cell), [`ActionSheetItem`](/components/action-sheet#action-sheet-item);

</Overview>

<Playground>
  ```jsx
  <Tappable onClick={() => alert('Обработчик нажатия')}>
    <Text>Я - кнопка</Text>
  </Tappable>
  ```
</Playground>

## Логика выбора элемента

Компонент динамически выбирает HTML-тег на основе переданных свойств:

| Условия              | Тег       | Роль/Атрибуты                 | Особенности                      |
| -------------------- | --------- | ----------------------------- | -------------------------------- |
| Передан `Component`  | Кастомный | Наследует переданные свойства | Требует ручной настройки a11y    |
| Указан `href`        | `<a>`     | `role="link"` при `disabled`  | Блокировка через `aria-disabled` |
| Указан `onClick`     | `<div>`   | `role="button" tabIndex="0"`  | Обработка клавиш Space/Enter     |
| Без `href`/`onClick` | `<div>`   | -                             | Неинтерактивный контейнер        |

## Особенности состояний

### Наведение

- Свойство `hasHover` включает/выключает реакцию на наведение.
- Свойство `hovered` включает состояние наведения.
- Свойство `hoverMode` позволяет стилизовать состояние.
  Если передать произвольную строку, она добавится как css-класс во время наведения.

### Нажатие

Задается свойством `active`:

- Свойство `hasActive` включает/выключает реакцию на нажатие.
- Свойство `activated` включает состояния нажатия.
- Свойство `activeMode`/`activeClassName` позволяет стилизовать состояние.
  Если передать произвольную строку, она добавится как css-класс во время нажатия.
- Свойство `activeEffectDelay` отвечает за длительность подсветки (в миллисекундах).

### Focus (фокус)

- Свойство `focusVisibleMode` позволяет стилизовать стиль состояния фокуса.
  Если передать произвольную строку, она добавится как css-класс при `:focus-visible`

## Скругление углов

Задается свойством `borderRadiusMode`:

- `auto` — адаптивный режим (нет скруглений на мобильных);
- `inherit` — наследование стилей.

## Взаимодействие с дочерними элементами

### Групповая подсветка

```jsx
// Родитель сохраняет hover при наведении на детей
<Tappable hasHoverWithChildren>
  <IconButton />
  <IconButton />
</Tappable>
```

### Проброс состояния

```jsx
// Дочерний элемент активирует hover родителя
<Tappable>
  <IconButton unlockParentHover />
</Tappable>
```

## Доступность (a11y) [#a11y]

### Основные принципы

- **Автоматическая семантика**

  Компонент сам выбирает подходящий HTML-тег:
  - `<a>` при передаче `href`;
  - `<div role="button">` при наличии `onClick`;
  - в остальных случаях `<div>`.

- **Блокировка элементов**

  При `disabled`:
  - Для ссылок: `aria-disabled="true"` + удаление `href`
  - Для кнопок: `aria-disabled="true"` + `tabIndex="-1"`

- **Клавиатурные события**

  Кнопки (`role="button"`) обрабатывают:
  - Нажатие клавиш `Space`/`Enter`
  - Фокус через клавишу `Tab`

### Критические правила

- **Иконки без текста**

  Всегда добавляйте текстовую метку:

  ```jsx
  // Плохо
  <Tappable><Icon16Close /></Tappable>

  // Хорошо
  <Tappable aria-label="Закрыть">
    <Icon16Close />
  </Tappable>
  ```

- **Смешение href и onClick**

  Избегайте комбинации — это нарушает семантику:

  ```jsx
  // Антипаттерн
  <Tappable href="/page" onClick={handleClick} />

  // Правильно
  <Tappable href="/page">Ссылка</Tappable>
  <Tappable onClick={handleClick}>Кнопка</Tappable>
  ```

- **Кастомные элементы**

  Для нестандартных тегов явно укажите:

  ```jsx
  <Tappable Component="span" role="button" tabIndex={0} aria-label="Действие" />
  ```

### Визуальный фокус

- Используйте `focusVisibleMode` для кастомизации.
- Не переопределяйте `:focus-visible` без веской причины.

## Свойства и методы [#api]

<PropsTable name="Tappable" />
